package com.gxa.ssm251.controller;

import com.gxa.ssm251.exception.BusinessException;
import com.gxa.ssm251.mapper.UserMapper;
import com.gxa.ssm251.pojo.User;
import com.gxa.ssm251.service.UserService;
import com.gxa.ssm251.util.JsonResult;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;


// http://localhost:8080/user/login
// dispatcherServlet通过/把所有请求都拦截下来,获取到其中 /user 部分
// 通过user寻找对应的控制器:通过类上的@RequestMapping找到对应的控制器类,
//在通过方法上的 @RequestMapping 匹配对应的操作
@Controller
@RequestMapping("/user")
//@RestController 把@ResponseBody和@Controller合二为一 完全适用于前后端分离,每个方法返回值都是json,没有返回字符串一说
public class UserCtontroller {
    /*@Resource
    private UserMapper userMapper = null;*/
    @Resource
    private UserService userService = null;

    JsonResult jsonResult = new JsonResult();

    @ApiOperation(value = "根据id查询用户信息的操作",notes = "需要强调的注意事项",
            response = Map.class,httpMethod ="get/post" )
    @ApiImplicitParams(
            @ApiImplicitParam(name = "id",value = "用户的编号",required = true,
                    dataType = "String",example = "1")
    )
    @PostMapping("/getUser")
    @ResponseBody
    public JsonResult selectById(@RequestParam("id")Integer id) throws BusinessException {
        JsonResult jsonResult=new JsonResult();
        User user1 = userService.selectById(id);
        if (user1 != null){
            jsonResult.setCode("1");
            jsonResult.setMsg("查询成功");
            jsonResult.setData(user1);
        }else {
            jsonResult.setCode("0");
            jsonResult.setMsg("没有此数据");
        }
        return jsonResult;
    }
//    依赖UserService的bean
    //    UserService service=null;
    //方式一:设计一个返回值为void的方法,只能响应到前端的请求
//    @RequestMapping("/login")
//    public void login() {
//        System.out.println("有请求发送给/user/login");
//    }
    //方式二:设计一个返回值为String的方法,能响应到前端的请求,并返回一个jsp
//    @RequestMapping(value = "/login", method = {RequestMethod.GET, RequestMethod.POST})
    @ApiOperation(value = "用户的登录方法",notes = "需要强调的注意事项",
            response = Map.class,httpMethod ="get/post" )
    @ApiImplicitParams(
            @ApiImplicitParam(name = "phone",value = "这是用户的手机号",required = true,
                    dataType = "String",example = "1",type = "body")
    )
    @ResponseBody
    @PostMapping("/login")
    public Map<String,Object> login(@RequestParam("phone")String phone,@RequestParam("pwd")String pwd) throws Exception {
        System.out.println("有请求发送给/user/login");
        //login通过视图解析器完成拼接: /WEB-INF/jsp/login.html
        /*在通过转发的方式访问jsp */
        return null;
    }


    @ApiOperation(value = "用户的添加方法",notes = "注意必填",
        response = Map.class,httpMethod = "post")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "User",value = "对象",required = false,
            dataType = "String",example = "1",type = "body")
    )
    @PostMapping("/insert")
    @ResponseBody
    public JsonResult insert(@RequestBody User user) throws Exception {
        Integer insert = userService.insert(user);
        if (insert>0){
            jsonResult.setCode("1");
            jsonResult.setMsg("添加成功");
            jsonResult.setData(user);
        }else {
            jsonResult.setCode("0");
            jsonResult.setMsg("添加失败");
        }
        return jsonResult;
    }

    @ApiOperation(value = "用户信息修改操作",notes = "注意事项，返回影响行数肯可能会不准确",
            response = Map.class,httpMethod ="get/post" )
    @ApiImplicitParams(
            @ApiImplicitParam(name = "id",value = "用户的编号",required = true,
                    dataType = "String",example = "1")
    )
    @PostMapping("/update")
    @ResponseBody
    public JsonResult update(@RequestBody User user){
        Integer update = userService.update(user);
        if (update>0){
            jsonResult.setCode("1");
            jsonResult.setMsg("修改成功");
            jsonResult.setData(user);
        }else {
            jsonResult.setCode("0");
            jsonResult.setMsg("修改失败");
        }
        return jsonResult;
    }

    /*分页查询*/
    @ApiOperation(value = "用户信息分页查询",notes = "注意事项",
            response = Map.class,httpMethod ="get/post" )
    @ApiImplicitParams(
            @ApiImplicitParam(name = "page/size",value = "页数/每页条数",required = false,
                    dataType = "String",example = "1")
    )
    @PostMapping("/selectByPage")
    @ResponseBody
    public JsonResult selectByPage(@RequestParam("page") Integer page,@RequestParam("size") Integer size){
        List<User> users = userService.selectByPage(page,size);
        if (users != null){
            jsonResult.setCode("1");
            jsonResult.setMsg("分页查询成功");
            jsonResult.setData(users);
        }else {
            jsonResult.setCode("0");
            jsonResult.setMsg("未查询到数据");
        }
        return jsonResult;
    }

    /*用户姓名或手机号进行模糊查询*/
    @ApiOperation(value = "用户信息模糊查询",notes = "注意事项",
            response = Map.class,httpMethod ="get/post" )
    @ApiImplicitParams(
            @ApiImplicitParam(name = "selectLikeNameOrPhone",value = "用户姓名或手机号",required = false,
                    dataType = "String",example = "1")
    )
    @PostMapping("/selectLikeNameOrPhone")
    @ResponseBody
    public JsonResult selectLikeNameOrPhone(@RequestParam("param") String param){
        List<User> users = userService.selectLikeNameOrPhone(param);
        if (users != null){
            jsonResult.setCode("1");
            jsonResult.setMsg("查询成功");
            jsonResult.setData(users);
        }else {
            jsonResult.setCode("0");
            jsonResult.setMsg("为查询到用户");
        }
        return jsonResult;
    }

    /*导出全部用户*/
    @ApiOperation(value = "导出全部用户",notes = "注意事项:可能用不起",
            response = Map.class,httpMethod ="get/post" )
    @ApiImplicitParams(
            @ApiImplicitParam(name = "exportUserInfo",value = "导出全部",required = false,
                    dataType = "String",example = "1")
    )
    @PostMapping("/exportUserInfo")
    @ResponseBody
    public void exportUser(HttpServletResponse response, HttpServletRequest request) throws Exception {
        response.setCharacterEncoding("UTF-8");
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        List<User> userList = userService.exportUserInfo();
       // System.out.println(userList);
        String filename = "用户管理表.xls";
        //创建excel文件
        HSSFWorkbook workbook =  new HSSFWorkbook();
        //创建sheet页面
        HSSFSheet sheet =  workbook.createSheet("用户信息管理表");
        //准备将时间格式处理为标准日期格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //创建标题行
        HSSFRow  hssfRow = sheet.createRow(0);
        hssfRow.createCell(0).setCellValue("编号");
        hssfRow.createCell(1).setCellValue("用户姓名");
       /* hssfRow.createCell(2).setCellValue("用户密码");*/
        hssfRow.createCell(2).setCellValue("用户电话号码");
        hssfRow.createCell(3).setCellValue("用户最后登录时间");
        hssfRow.createCell(4).setCellValue("用户身份证号码");
        hssfRow.createCell(5).setCellValue("用户备注");
        hssfRow.createCell(6).setCellValue("保险公司");
        hssfRow.createCell(7).setCellValue("被保险人");
        hssfRow.createCell(8).setCellValue("车牌号");
        hssfRow.createCell(9).setCellValue("车型");
        hssfRow.createCell(10).setCellValue("发动机号码");
        hssfRow.createCell(11).setCellValue("投保日期");

        //遍历，将信息放到excel表中
        for (User user : userList) {
            HSSFRow hssfRow1 = sheet.createRow(sheet.getLastRowNum()+1);
            hssfRow1.createCell(0).setCellValue(user.getId());
            hssfRow1.createCell(1).setCellValue(user.getName());
            //hssfRow1.createCell(2).setCellValue(user.getPwd());
            hssfRow1.createCell(2).setCellValue(user.getPhone());
            hssfRow1.createCell(3).setCellValue(dateFormat.format(user.getFnlTime()));
            hssfRow1.createCell(4).setCellValue(user.getIdCar());
            hssfRow1.createCell(5).setCellValue(user.getRemarks());
            hssfRow1.createCell(6).setCellValue(user.getInsuranceName());
            hssfRow1.createCell(7).setCellValue(user.getInsyredPerson());
            hssfRow1.createCell(8).setCellValue(user.getBrandCar());
            hssfRow1.createCell(9).setCellValue(user.getCarModel());
            hssfRow1.createCell(10).setCellValue(user.getCarEngine());
            hssfRow1.createCell(11).setCellValue(user.getRegTime());
        }
        // 设置下载时客户端Excel的名称（上面注释的改进版本，上面的中文不支持）
        response.setContentType("application/octet-stream;charset=utf-8");
        /*response.setHeader("Content-Disposition", "attachment;filename="
                + new String("用户名单".getBytes(),"iso-8859-1") + ".xls");*/
        response.setHeader("Content-Disposition","attachment;filename="+filename);

        OutputStream outputStream =  response.getOutputStream();
        workbook.write(outputStream);
        outputStream.flush();
        outputStream.close();
    }
  /*  *//**
     * @param modelAndView 表示用spring的方式创建一个bean,
     *                     在mvc(springMvc)中,声明的参数往往都能自动注入(DI)
     * @return
     *//*
    @RequestMapping("/loginInModel")
    public ModelAndView loginInModel(ModelAndView modelAndView) {
        //Model:数据模型
        //ModelMap:数据的映射
        //ModelAndView:数据和视图的整合对象

        //指定数据
        User user = new User();
        user.setName("张无忌");
        //作为数据模型 model
        modelAndView.addObject(user);
        //指定视图名称,并用转发的方式跳转到jsp页面上
        modelAndView.setViewName("login");

        //作用:在目标jsp页面中获取model数据:{user}

        return modelAndView;
    }
    //通过model赋值

    //    @PostMapping(value = "/loModel")
    @RequestMapping(value = "/loModel", method = {RequestMethod.GET, RequestMethod.POST})
    public String loMdel(Model model) {
        User user = new User();
        user.setName("赵敏");
        model.addAttribute("user", user);
        return "login";
    }


    //方式四:如何在接口上带参 @RequestParam
    //@RequestParam 必须声明才参数中
    //value 传参时使用的名字
    //如果不带注解也可以完成注入,但缺少控制
    //默认的是true, required = true 是指参数必须要的

//    @PostMapping(value = "/reg")
//    public void register(@RequestParam(value = "phone",required = true) String phone, @RequestParam("pwd") String pwd) {
//        System.out.println("phone = " + phone);
//        System.out.println("pwd = " + pwd);
//    }

    // defaultValue: 默认值 , 可以用在分页中默认为第1页, 还可以用在查询条件(条件为空就全查询,有条件就模糊查询)的
    // 如果不带注解也可以完成注入,但缺少控制
//    @PostMapping("/register")
//    public void register(@RequestParam(value = "phone",required = false,defaultValue = "133") String phone,String pwd){
//        System.out.println("phone:"+phone);
//        System.out.println("pwd:"+pwd);
//    }

//    方式五: 在接口中带入多个参数,属于同一个对象的特征 User
    //@RequestBody: 传入多个参数给对象注入
    //前端传参不能通过param,而要传递json字符串
    //data:{"name":"zhang"}  json的对象(序列化)
    //data: JSON.stringfy({"name":"zhang"}) json的字符串
//    @PostMapping("/register")
//    public void register(@RequestBody User user){
//        System.out.println("user:"+user);
//
//    }

    @PostMapping("/index")
//    @RequestMapping(value = "/index", method = {RequestMethod.GET, RequestMethod.POST})
    public void index(@RequestHeader("methed") String methed) {
        System.out.println("methed = " + methed);
    }

    // 方式六:给前端响应,前端需要什么,就返回什么
    //还需要@ResponseBody 告诉mvc,响应的内容是json对象
    //注意事项:
    //1.不是json字符串,可以通过key访问value
    //2.如果此时返回字符串,前端将直接看到字符串(没有用)
    //3.给前端返回集合
    //4.给前端返回jsonResult(code/msg/data)
    //5.@ResponseBody 还可以声明在类上,每个方法都返回json(适用于前后端分离)
    //6.当控制器是一个完整的前后端分离(代表该接口是一个数据接口),可以用@RestController代替@Controller和 @ResponseBody
//    @PostMapping("/register")
//    @ResponseBody
//    public User register(@RequestBody User user) {
//        user.setId(1001);
//        return user;
//    }
//    @PostMapping("/register")
//    @ResponseBody
//    public String register(@RequestBody User user) {
//        user.setId(1001);
//        return "login";
//    }
//    @PostMapping("/register")
//    @ResponseBody
//    public List<User> register(@RequestBody User user) {
//        user.setId(1001);
//        List<User> userList=new ArrayList<>();
//        userList.add(new User("nihao"));
//        userList.add(new User("娲女"));
//        userList.add(new User("nih太一ao"));
//        return userList;
//    }
//    @PostMapping("/register")
//    @ResponseBody
//    public Map<String,Object> register(@RequestBody User user) {
//
//        List<User> userList=new ArrayList<>();
//        userList.add(new User("nihao"));
//        userList.add(new User("娲女"));
//        userList.add(new User("nih太一ao"));
//        JsonResult jsonResult=new JsonResult();
//        jsonResult.setData(userList);
//        jsonResult.setCode("1");
//        jsonResult.setMsg("注册成功");
//        return jsonResult.getValues();
//    }


    @Resource
    UserService userService = null;
    //Controller调用Service
    //处理json中可能存在的中文乱码问题
    @PostMapping(value = "/register")
    @ResponseBody
    public Map<String, Object> register(@RequestBody User user) throws Exception {
        JsonResult jsonResult = new JsonResult();
        //调用UserService真正完成业务
        Integer register = userService.register(user);
        if ((register > 0)) {
            jsonResult.setData(user);
            jsonResult.setCode("1");
            jsonResult.setMsg("注册成功");
        } else {
//            throw new BusinessException("")
        }

        return jsonResult.getValues();
    }

//    @ExceptionHandler
//    异常处理方式，当某一个类中有此方法时，此类任何处理报错，都会执行此方法内容，而不会在前端抛出500的异常
    @ExceptionHandler(Throwable.class)
    public String check() {
        System.out.println("挂了吧，开心");
        return "login";
    }
//    PS:注意，可以自定义异常处理，但是引入的class必须是Throwable的子类
*/
}
